;	EXPERIMENTAL I/O SYSTEM

R0	=	%0
R1	=	%1
R2	=	%2
R3	=	%3
R4	=	%4
R5	=	%5
SP	=	%6
PC	=	%7

LPT0	=	177514
HSR0	=	177550
HSP0	=	177554
KBD0	=	177560
TTY0	=	177564
SWREG	=	177570
STATUS	=	177776

;	MACRO DEFINITIONS



;	VECTOR----SET UP A TRAP OR INTERRUPT VECTOR

	.MACR	VECTOR	QQ1,QQ2,QQ3
	.=QQ1
	.WORD	QQ2
	.WORD	QQ3
	.ENDM


;	SAVSTS----SAVE THE CURRENT PROCESSOR STATUS

	.MACR	SAVSTS
	CCC
	MOV	@#STATUS,-(SP)
	MOV	#340,@#STATUS
	.ENDM


;	RSTSTS----RESTORE THE PROCESSOR STATUS

	.MACR	RSTSTS
	MOV	(SP)+,@#STATUS
	.ENDM


;	BUFFER----ALLOCATE A BUFFER

	.MACR	BUFFER	QQ1,QQ2,QQ3
QQ2:	.REPT	QQ1
	.WORD	0
	.ENDR
QQ3=.-1
	.ENDM


;	SET UP THE USED TRAP AND INTERRUPT VECTORS

	VECTOR	60,DPK0IN,000200	;KBD0 INTERRUPT LEVEL 4
	VECTOR	64,DPS0IN,000200	;TTY0 INTERRUPT LEVEL 4
	VECTOR	70,HSR0IN,000200	;HSR0 INTERRUPT LEVEL 4
	VECTOR	74,HSP0IN,000200	;HSP0 INTERRUPT LEVEL 4
	VECTOR	200,LPT0IN,000240	;LPT0 INTERRUPT LEVEL 5

.=2000

START:	MOV	#.,SP		;SET UP A STACK
	CLR	STATUS
	RESET			;GO AWAY WORLD!!
	HALT
	MOV	#101,KBD0	;TURN ON THE LSR
	MOV	#101,HSR0	;TURN ON THE HSR
ST01:	BIT	#1,SWREG	;SEE IF BIT 0 IS ON
	BNE	ST03		;EMPTY THE INPUT
ST02:	BIT	#2,SWREG	;SEE IF INIT IS WANTED
	BNE	ST04
ST05:	TST	SWREG		;SEE IF BIT 15 IS ON
	BPL	ST01		;IF NOT LOOP AROUND
	MOV	#MSG,R2		;SET UP BUFFER ADDRESS
	MOV	#0,R1		;SET SLOT
	JSR	PC,OUTPUT	;GO BABY GO
	BR	ST01
ST03:	MOV	#BUFFR,R2	;A BIG PLACE FOR JUNK
	MOV	#0,R1		;THE SLOT
	JSR	PC,INPUT
	BVS	ST02		;IF EOF THEN QUIT!
	MOV	#0,R1
	JSR	PC,OUTPUT
	MOV	#80.,R1
	CLR	(R2)+
	DEC	R1
	DEC	R1
	BGT	.-6
	BR	ST02
ST04:	MOV	#0,R1
	JSR	PC,INITI	;INIT THE INPUT SLOT
	MOV	#100000,R2	;WAIT FOR A "REAL TIME
ST07:	ADD	#1,R2		;I KNOW IT'S A FUNNY INCREMENT
	BVC	ST07		;BUT IT TAKES LONGER
	MOV	#100000,R2	;A LONG "REAL" TIME
ST08:	ADD	#1,R2
	BVC	ST08
	BR	ST05		;BACK TO THE SCAN

BUFFR	=	.
	.	=	.+160.
MSG:	.ASCII	#THIS IS THE WAY WE TYPE ON THE TTY------#
	.BYTE	15,12,0
	.EVEN

TRAILR:	CMP	R1,#2		;SEE WHICH SLOT
	BGT	I.TR03		;IF LPT THEN <FF>
	BLT	I.TR05		;IF TTY THEN EXIT NOW
	MOV	#20.,-(SP)	;20 FRAMES OF NULL WILL DO
	MOV	SLOTSO(R1),R0	;GET THE BUFFER
	CLR	R1
I.TR01:	JSR	PC,PTBYT
	BVS	I.TR02
	DEC	(SP)
	BGT	I.TR01		;LOOP IF MORE TO DO
	TST	(SP)+
I.TR05:	MOV	(SP)+,R1	;RESTORE THE REGS
	MOV	(SP)+,R0
	RTS	PC
I.TR02:	WAIT
	BR	I.TR01		;HOPE FOR OUR INTERRUPT
I.TR03:	MOV	#014,R1		;MOVE A <FF>
I.TR07:	JSR	PC,PTBYT	;PUT IT OUT
	BVS	I.TR04
	BR	I.TR05
I.TR04:	WAIT
	BR	I.TR07

INITI:	MOV	SLOTSI(R1),R0	;GET THE BUFFER ADDRESS
	MOV	B.GET(R0),B.PUT(R0)	;EMPTY IT
	CLR	B.STUS(R0)
	CLR	B.SPEC(R0)	;CLEAR MISC FLAGS
	BIS	#101,@(R0)	;ENABLE READER
	RTS	PC
;	BUFFER MANAGMENT ROUTINES

B.DEV	=	0	;DEVICE ADDRESS IS THE FIRST WORD
B.STRT	=	2	;START IS THE SECOND WORD OF THE BUFFER HEADER
B.END	=	4	;END IS THE THIRD WORD OF THE BUFFER HEADER
B.GET	=	6	;GET IS THE FOURTH WORD OF THE BUFFER HEADER
B.PUT	=	10	;PUT IS THE FIFTH WORD OF THE BUFFER HEADER
B.STUS	=	12	;STATUS IS THE SIXTH WORD OF THE BUFFER HEADER
B.SPEC	=	14	;SPECIAL WORD FOR READERS AND LINE COUNT


;	GTBYT--GET A BYTE OUT OF THE BUFFER
;		R0 POINTS TO THE BUFFER HEADER
;		R1 HAS THE CHARACTER UPON EXIT
;		THE V BIT IS SET IF NO BYTES ARE AVAILABLE

GTBYT:	SAVSTS			;SAVE THE PRIORITY
	MOV	B.GET(R0),R1	;GET POINTER TO R1
	CMP	R1,B.PUT(R0)	;SEE IF THERE IS ANYTHING IN THERE
	BEQ	B.GB01		;IF EQUAL THE BUFFER IS EMPTY
	MOVB	(R1)+,-(SP)	;GET THE BYTE
	CMP	R1,B.END(R0)	;SEE IF WE WRAPED AROUND
	BLOS	B.GB02		;IF OK THEN BYPASS 
	MOV	B.STRT(R0),R1	;WRAP AROUND
B.GB02:	MOV	R1,B.GET(R0)	;PUT AWAY THE NEW GET POINTER
	CLR	R1		;CLEAR R1
	BISB	(SP)+,R1	;GET THE BYTE
	RSTSTS
	RTS	PC		;AND RETURN
B.GB01:	RSTSTS
	SEV			;SET NOT FOUND
	RTS	PC		;AND RETURN

;	PTBYT--PUT A BYTE IN THE BUFFER
;		R0 POINTS TO THE BUFFER HEADER
;		R1 HAS THE CHARACTER
;		THE V BIT IS SET IF THE CHARACTER CAN NOT BE ENTERED

PTBYT:	SAVSTS			;SAVE THE STATUS AND GO MASKED
	MOV	R1,-(SP)	;SAVE R1 SO WE CAN USE A REGISTER LATTER
	MOV	B.PUT(R0),R1	;GET THE PUT POINTER
	INC	R1		;GET THE POSSIBLE NEW POSITION
	CMP	R1,B.END(R0)	;SEE IF IT WOULD WRAP AROUND
	BLOS	B.PB02		;SKIP IF OK
	MOV	B.STRT(R0),R1	;WRAP AROUND
B.PB02:	CMP	R1,B.GET(R0)	;SEE IF THERE IS ROOM
	BEQ	B.PB01		;IF EQUAL NO ROOM
	MOVB	(SP),@B.PUT(R0)	;STORE THE BYTE
	MOV	R1,B.PUT(R0)	;STORE THE NEW PUT POINTER
	MOV	(SP)+,R1	;RESTORE R1
	RSTSTS
	RTS	PC		;AND RETURN
B.PB01:	MOV	(SP)+,R1	;RESTORE R1
	RSTSTS
	SEV			;SHOW NO ROOM AT ALL!
	RTS	PC		;AND RETURN

;	BKBYT--BACKSPACE A BUFFER
;		R0 POINTS TO THE BUFFER HEADER
;		R1 CONTAINS THE DELETED CHARACTER UPON EXIT
;		THE V BIT IS SET IF THERE ARE NO BYTES AVAILABLE

BKBYT:	SAVSTS			;ELIMINATE THE OUTSIDE INTERFERENCE
	MOV	B.PUT(R0),R1	;GET THE PUT POINTER
	CMP	R1,B.GET(R0)	;SEE IF THERE'S ANYTHING
	BEQ	B.BB01		;BRANCH IF NONE
	MOVB	-(R1),-(SP)	;GET THE BYTE AND SAVE IT
	CMP	R1,B.STRT(R0)	;SEE IF WE WRAP AROUND
	BHIS	B.BB00		;BRANCH IF NO HARM
	MOV	B.END(R0),R1	;WRAP AROUND
B.BB00:	MOV	R1,B.PUT(R0)	;PUT AWAY THE POINTER
	CLR	R1
	BISB	(SP)+,R1	;GET THE BYTE
	RSTSTS
	RTS	PC
B.BB01:	RSTSTS
	SEV			;TELL HIM NOBODYS HOME
	RTS	PC

;	RTBYT--RETURN A BYTE TO THE BUFFER
;		R0 POINTS TO THE BUFFER HEADER
;		R1 IS THE BYTE TO BE RETURNED
;		THE V BIT SI SET IF THERE IS NO ROOM

RTBYT:	SAVSTS			;WE BUFFER MANAGEMENT ROUTINES ARE GOD!
	MOV	R1,-(SP)	;SAVE THE CHARACTER FOR LATTER
	MOV	B.GET(R0),R1	;GET THE GET POINTER
	DEC	R1		;BACK UP ONE BYTE
	CMP	R1,B.STRT(R0)	;SEE IF THIS IS STILL THE BUFFER
	BHIS	B.RB01		;IF OK THEN SKIP
	MOV	B.END(R0),R1	;WRAP ROUND
B.RB01:	CMP	R1,B.PUT(R0)	;SEE IF IT IS FULL
	BEQ	B.RB00		;IF EQUAL THEN FULL BUDDY!
	MOVB	(SP),(R1)	;STORE THE BYTE
	MOV	R1,B.GET(R0)	;UPDATE THE GET POINTER
B.RB02:	MOV	(SP)+,R1	;GET BACK THE OLD R1
	RSTSTS
	RTS	PC
B.RB00:	RSTSTS
	SEV			;SHOW A TIGHT SQUEZ
	RTS	PC

I.ATB1:	.BYTE	177	;RUBOUT
	.BYTE	175	;ALT
	.BYTE	033	;ESC
	.BYTE	025	;^U
	.BYTE	017	;^O
	.BYTE	003	;^C
	.BYTE	015	;CR
	.BYTE	012	;LF
	.EVEN



SLOTSO:	.WORD	TTYBUF	;SLOT 0 IS TTY
	.WORD	HSPBUF	;SLOT 2 IS HSP
	.WORD	LPTBUF	;SLOT 4 IS LPT



SLOTSI:	.WORD	KBDBUF	;SLOT 0 IS KBD
	.WORD	HSRBUF	;SLOT 2 IS HSR
	.WORD	SWREG	;SLOT 4 IS SWITCH REGISTER

KBD0IN:	MOV	R2,-(SP)	;SAVE THE IMPORTANT REGISTERS
	MOV	R1,-(SP)
	MOV	R0,-(SP)
	MOV	KBD0+2,R1	;GET THE CHARACTER
	BIC	#177600,R1	;CLEAR THE PARITY BIT
	BEQ	I.KB06		;IF NULL IGNORE
	MOV	#KBDBUF,R0	;SET UP THE BUFFER ADDRESS
	MOV	#I.ATB1,R2	;A TABLE OF SPECIAL CHARACTERS
	CMPB	R1,(R2)+
	BEQ	I.KB03		;IF EQUAL THEN <RUBOUT>
	BIT	#200,B.STUS(R0)	;SEE IF WE NEED A TRAILING _
	BEQ	I.KB00
	JSR	PC,I.PRBA	;PRINT A BACK ARROW(_)
	BIC	#200,B.STUS(R0)	;CLEAR RUBOUT FLAG
I.KB00:	CMPB	R1,(R2)+
	BEQ	I.KB07		;IF EQUAL THEN <ALT>
	CMPB	R1,(R2)+
	BEQ	I.KB07		;IF EQUAL THEN <ESC>
	CMPB	R1,(R2)+
	BEQ	I.KB08		;IF EQUAL THEN <^U>
	CMPB	R1,(R2)+
	BEQ	I.KB09		;IF EQUAL THEN <^O>
	CMPB	R1,(R2)+
	BEQ	I.KB0A		;IF EQUAL THEN <^C>
	JSR	PC,PTBYT	;IF NOT SPECIAL THEN ENTER IT
	BVS	I.KB0Z		;BRANCH IF FULL
I.KB05:	SUB	#14,R0		;GO TO THE ECHO BUFFER
	JSR	PC,PTBYT	;ECHO IT A WELL
	CMPB	R1,(R2)+
	BNE	I.KB01		;IF A <CR> MORE WORK IS CALLED FOR
	MOVB	#012,R1
	JSR	PC,PTBYT	;STILL THE ECHO BUFFER
	ADD	#14,R0		;BACK TO THE KBD BUFF
	JSR	PC,PTBYT	;TRY TO ENTER IT
	BVS	I.KB0Z		;IF OVER FLOW THEN BAD
	BR	I.KB02
I.KB01:	ADD	#14,R0		;BACK TO THE KBD BUFF
I.KB02:	CMPB	R1,(R2)+
	BNE	I.KB06		;IF EQUAL THEN <LF>
	INCB	B.SPEC(R0)	;INCREMENT THE LINE COUNT
I.KB06:	BIS	#101,@(R0)	;RE-ENABLE THE READER
	BIS	#100,@16(R0)	;TURN THE TTY ON FOR A STRECH
I.KB0C:	MOV	(SP)+,R0	;RESTORE THE REGS
	MOV	(SP)+,R1
	MOV	(SP)+,R2
	RTI

I.PRBA:	MOV	R1,-(SP)	;SAVE THE CURRENT CHARACTER
	MOVB	#'_,R1		;GET READY FOR A _
	SUB	#14,R0		;GET TO THE ECHO BUFF
	JSR	PC,PTBYT
	ADD	#14,R0		;BACK TO THE KBD BUFF
	MOV	(SP)+,R1	;GET THE CHARACTER
	RTS	PC
I.PRUP:	MOV	R1,-(SP)	;PUSH THE CHARACTER
	SUB	#14,R0		;GO TO THE ECHO BUFFER
	MOVB	#'^,R1		;GET THE ^ PART
	JSR	PC,PTBYT	;PRINT IT
	MOV	(SP)+,R1	;GET THE CHARACTER BACK
	ADD	#100,R1		;CONVERT TO ASCII
	JSR	PC,PTBYT	;PRINT IT
	MOVB	#015,R1		;INSERT A <CR><LF> TOO
	JSR	PC,PTBYT
	MOVB	#012,R1
	JSR	PC,PTBYT
	ADD	#14,R0		;BACK TO THE KBD BUFF
	RTS	PC
I.KB03:	BIT	#200,B.STUS(R0)	;SEE IF THIS IS THE FIRST ONE
	BNE	I.KB04
	JSR	PC,I.PRBA	;PRINT _
	BIS	#200,B.STUS(R0)	;SET RUBOUT IN PROGRESS
I.KB04:	JSR	PC,BKBYT	;SEE IF THERE IS ANY THING TO GET
	BVS	I.KB06
	CMPB	R1,#012
	BNE	I.KB05		;IF NOT A <LF> TYPE IT
	JSR	PC,PTBYT	;ELSE PUT IT BACK
	BR	I.KB06
I.KB07:	MOVB	#'$,R1		;ECHO A $
	SUB	#14,R0		;GO TO THE ECHO BUFF
	JSR	PC,PTBYT	;OUTPUT IT
	ADD	#14,R0		;BACK TO THE KBD BUFFER
I.KB0B:	JSR	PC,BKBYT
	BVS	I.KB06		;IF NONE EXIT
	CMPB	R1,#012
	BNE	I.KB0B		;IF NOT <LF> TRY AGAIN
	JSR	PC,PTBYT	;RETURN IT DUMBIE
	BR	I.KB06
I.KB08:	JSR	PC,I.PRUP	;PRINT ^U
	BR	I.KB0B		;HANDLE LIKE ALT AND ESC
I.KB09:	JSR	PC,I.PRUP	;PRINT ^O
	BIS	#10,B.STUS(R0)	;SET ^O FLAG
	BR	I.KB06		;AND EXIT
I.KB0A:	JSR	PC,I.PRUP
	MOV	(SP)+,R0
	MOV	(SP)+,R1	;RESTORE THE REGS
	MOV	(SP)+,R2
	JMP	@50
I.KB0Z:	MOVB	R1,B.SPEC+1(R0)	;SAVE THE CHARACTER
	BIS	#400,B.STUS(R0)	;TELL HIM WHAT WE DID
	BR	I.KB0C		;DON'T--I SAY DON'T ENABLE THE READER

DPK0IN:	MOV	R2,-(SP)	;SAVE THE IMPORTANT REGISTERS
	MOV	R1,-(SP)
	MOV	R0,-(SP)
	MOV	KBD0+2,R1	;GET THE CHARACTER
	BIC	#177600,R1	;CLEAR THE PARITY BIT
	BEQ	I.DK06		;IF NULL IGNORE
	MOV	#KBDBUF,R0	;SET UP THE BUFFER ADDRESS
	MOV	#I.ATB1,R2	;A TABLE OF SPECIAL CHARACTERS
	CMPB	R1,(R2)+
	BEQ	I.DK03		;IF EQUAL THEN <RUBOUT>
I.DK00:	CMPB	R1,(R2)+
	BEQ	I.DK07		;IF EQUAL THEN <ALT>
	CMPB	R1,(R2)+
	BEQ	I.DK07		;IF EQUAL THEN <ESC>
	CMPB	R1,(R2)+
	BEQ	I.DK08		;IF EQUAL THEN <^U>
	CMPB	R1,(R2)+
	BEQ	I.DK09		;IF EQUAL THEN <^O>
	CMPB	R1,(R2)+
	BEQ	I.DK0A		;IF EQUAL THEN <^C>
	JSR	PC,PTBYT	;IF NOT SPECIAL THEN ENTER IT
	BVS	I.DK0Z		;BRANCH IF FULL
I.DK05:	SUB	#14,R0		;GO TO THE ECHO BUFFER
	JSR	PC,PTBYT	;ECHO IT A WELL
	CMPB	R1,(R2)+
	BNE	I.DK01		;IF A <CR> MORE WORK IS CALLED FOR
	MOVB	#012,R1
	JSR	PC,PTBYT	;STILL THE ECHO BUFFER
	ADD	#14,R0		;BACK TO THE KBD BUFF
	JSR	PC,PTBYT	;TRY TO ENTER IT
	BVS	I.DK0Z		;IF OVER FLOW THEN BAD
	BR	I.DK02
I.DK01:	ADD	#14,R0		;BACK TO THE KBD BUFF
I.DK02:	CMPB	R1,(R2)+
	BNE	I.DK06		;IF EQUAL THEN <LF>
	INCB	B.SPEC(R0)	;INCREMENT THE LINE COUNT
I.DK06:	BIS	#101,@(R0)	;RE-ENABLE THE READER
	BIS	#100,@-30(R0)	;TURN THE TTY ON FOR A STRECH
I.DK0C:	MOV	(SP)+,R0	;RESTORE THE REGS
	MOV	(SP)+,R1
	MOV	(SP)+,R2
	RTI
I.DK03:	JSR	PC,BKBYT	;SEE IT THERE'S ANYTHING
	BVS	I.DK06		;IF NOTHING THEN EXIT
	SUB	#14,R0		;FO TO THE ECHO BUFFER
	MOVB	#031,R1		;CURSOR LEFT
	JSR	PC,PTBYT
	MOVB	#036,R1		;DRASE EOL
	JSR	PC,PTBYT
	ADD	#14,R0		;BACK TO THE REGULAR BUFFER
	BR	I.DK06		;EXIT
I.DK08:
I.DK07:	SUB	#14,R0		;GO TO THE ECHO BUFF
	MOVB	#015,R1		;<CR>
	JSR	PC,PTBYT
	MOVB	#036,R1		;ERASE EOL
	JSR	PC,PTBYT
	JSR	PC,PTBYT	;OUTPUT IT
	ADD	#14,R0		;BACK TO THE KBD BUFFER
I.DK0B:	JSR	PC,BKBYT
	BVS	I.DK06		;IF NONE EXIT
	CMPB	R1,#012
	BNE	I.DK0B		;IF NOT <LF> TRY AGAIN
	JSR	PC,PTBYT	;RETURN IT DUMBIE
	BR	I.DK06
I.DK09:	JSR	PC,I.PRUP	;PRINT ^O
	BIS	#10,B.STUS(R0)	;SET ^O FLAG
	BR	I.DK06		;AND EXIT
I.DK0A:	JSR	PC,I.PRUP
	MOV	(SP)+,R0
	MOV	(SP)+,R1	;RESTORE THE REGS
	MOV	(SP)+,R2
	JMP	@50
I.DK0Z:	MOVB	R1,B.SPEC+1(R0)	;SAVE THE CHARACTER
	BIS	#400,B.STUS(R0)	;TELL HIM WHAT WE DID
	BR	I.DK0C		;DON'T--I SAY DON'T ENABLE THE READER

TTYBUF:	.WORD	TTY0	;DEVICE ADDRESS
	.WORD	TP1	;START
	.WORD	TP2	;END
	.WORD	TP1	;GET
	.WORD	TP1	;PUT
	.WORD	0	;STATUS

ECOBUF:	.WORD	0	;DEVICE ADDRESS
	.WORD	EB1	;START
	.WORD	EB2	;END
	.WORD	EB1	;GET
	.WORD	EB1	;PUT
	.WORD	0	;STATUS

KBDBUF:	.WORD	KBD0	;DEVICE ADDRESS
	.WORD	KB1	;START
	.WORD	KB2	;END
	.WORD	KB1	;GET
	.WORD	KB1	;PUT
	.WORD	0	;STATUS
	.WORD	0	;SPECIAL WORD

HSRBUF:	.WORD	HSR0	;DEVICE ADDRESS
	.WORD	HR1	;START ADDRESS
	.WORD	HR2	;END ADDRESS
	.WORD	HR1	;GET ADDRESS
	.WORD	HR1	;PUT ADDRESS
	.WORD	0	;STATUS
	.WORD	0	;SPECIAL WORD

HSPBUF:	.WORD	HSP0	;DEVICE ADDRESS
	.WORD	HP1	;START
	.WORD	HP2	;END
	.WORD	HP1	;GET
	.WORD	HP1	;PUT
	.WORD	0	;STATUS

LPTBUF:	.WORD	LPT0	;DEVICE ADDRESS
	.WORD	LP1	;START
	.WORD	LP2	;END
	.WORD	LP1	;GET
	.WORD	LP1	;PUT
	.WORD	0	;STATUS

TTY0IN:	MOV	R0,-(SP)	;SAVE R0 AND R1
	MOV	R1,-(SP)	;FOR USE IN THE DRIVER
	MOV	#ECOBUF,R0	;TRY THE ECHO BUFFER FIRST
	JSR	PC,GTBYT	;SEE IF ANY BODY'S HOME
	BVC	T00		;IF V OFF WE GOT HIM
	MOV	#TTYBUF,R0	;SEE ABOUT THE TTY BUFFER
	JSR	PC,GTBYT	;ANY CHARACTERS HERE?
	BVS	T01		;ALL GONE!
T00:	MOV	R1,TTY0+2		;OUTPUT THE CHARACTER
T02:	MOV	(SP)+,R1	;RESTORE THE REGISTERS
	MOV	(SP)+,R0	;LIKE A GOOD LITTLE BOY
	RTI			;WHITHER WANDEREST THOU WAYFARER
T01:	BIC	#100,TTY0	;TURN OFF THE BLOODY INTERRUPTS
	BR	T02		;AND EXIT

HSR0IN:	MOV	R0,-(SP)	;SAVE THE REGISTERS
	MOV	R1,-(SP)
	MOV	#HSRBUF,R0	;POINT TO THE HSR BUFF
	TST	HSR0		;TEST FOR EOF
	BMI	I.HR0X	;BRANCH IF ERROR
	MOV	HSR0+2,R1	;GET THE CHARACTER
	BIC	#177600,R1	;AND CLEAR PARITY
	BEQ	I.HR01		;IF NULL OR BLANK IGNORE IT
	CMP	R1,#177		;IF <RUBOUT> THROW AWAY
	BEQ	I.HR01
	JSR	PC,PTBYT	;TRY TO PUT IT AWAY
	BVS	I.HR0Z		;IF FULL OH NO
	CMPB	R1,#012		;SEE IF A WHOLE LINE
	BNE	I.HR01		;BRANCH IF NOT A LINE
	INCB	B.SPEC(R0)	;INCREMENT A COUNTER
I.HR01:	BIS	#101,HSR0	;RE-ENABLE THE READER
I.HR00:	MOV	(SP)+,R1
	MOV	(SP)+,R0	;RESTORE THE REGS
	RTI			;AND EXIT
I.HR0Z:	MOVB	R1,B.SPEC+1(R0)	;SAVE THE CHARACTER
	BIS	#400,B.STUS(R0)	;SHOW STOPPED READER
	BR	I.HR00
I.HR0X:	BIS	#1000,B.STUS(R0)	;SET EOF
	BR	I.HR00

HSP0IN:	MOV	R0,-(SP)	;SAVE THE REGS
	MOV	R1,-(SP)
	MOV	#HSPBUF,R0	;POINT TO THE HSP BUFF
	JSR	PC,GTBYT	;SEE IF ANY GOOD JUICE
	BVS	I.HP00
	MOV	R1,HSP0+2	;OUTPUT THE BYTE
I.HP01:	MOV	(SP)+,R1
	MOV	(SP)+,R0	;RESTORE THE REGS
	RTI
I.HP00:	BIC	#100,HSP0	;CLEAR THE INTERRUPTS
	BR	I.HP01

LPT0IN:	MOV	R0,-(SP)	;SAVE THE REGISTERS WE USE
	MOV	R1,-(SP)	;BOTH OF THEM
	MOV	#LPTBUF,R0	;SET UP THE POINTER TO LPTBUF
I.LP00:	JSR	PC,GTBYT	;GET A CHARACTER
	BVS	I.LP0Z		;IF EMPTY GET LOST
	CMPB	R1,#011		;SEE IF IT'S A <TAB>
	BNE	I.LP01		;IF NOT THEN GO PUT IT OUT
	TST	B.STUS(R0)	;SEE IF WE'VE PUT IN ENOUGH SPACES
	BMI	I.LP08		;IF WE HAVE THEN OK
	JSR	PC,RTBYT	;ELSE RETURN IT TO THE BUFFER
	MOV	#' ,R1		;PRINT A SPACE
	MOV	R1,LPT0+2	;OUTPUT THE CHARACTER
	ADD	#010000,B.STUS(R0)	;ADD ONE TO THE POSITION COUNTER
	BR	I.LP03		;FINISH UP
I.LP01:	CMPB	R1,#015		;SEE IF A POSITION MODIFIER
	BEQ	I.LP05
	CMPB	R1,#012		;<CR>,<LF>,<FF> ARE THE ONES
	BEQ	I.LP05
	CMPB	R1,#014
	BEQ	I.LP05
	ADD	#010000,B.STUS(R0)	;MOVE OVER ROVER
	BIC	#100000,B.STUS(R0)	;CLEAR CONFLICT WITH <TAB>
I.LP02:	MOV	R1,LPT0+2	;OUTPUT THE CHARACTER
I.LP03:	TSTB	LPT0		;SEE IF ONE OF 20
	BMI	I.LP00		;IF READY FEED HIM AGAIN
I.LP04:	MOV	(SP)+,R1	;RESTORE THE REGISTERS
	MOV	(SP)+,R0
	RTI
I.LP0Z:	BIC	#100,@(R0)
	BR	I.LP04		;TURN OFF INTERRUPTS AND RETURN
I.LP05:	BIC	#170000,B.STUS(R0)	;BACK TO POSITION ONE
	BR	I.LP02
I.LP08:	BIC	#170000,B.STUS(R0)	;CLEAR THE COUNTER
	BR	I.LP00		;GO GET ANOTHER

DPS0IN:	MOV	R0,-(SP)	;SAVE THE REGISTERS WE USE
	MOV	R1,-(SP)	;BOTH OF THEM
I.DS00:	MOV	#ECOBUF,R0	;SET UP THE POINTER TO LPTBUF
	JSR	PC,GTBYT	;GET A CHARACTER
	BVC	I.DS06		;IF WE GOT ONE OK
	MOV	#TTYBUF,R0	;IF NOT SEE ABOUT THE TTY
	JSR	PC,GTBYT
	BVS	I.DS0Z		;IF EMPTY GET LOST
I.DS06:	CMPB	R1,#011		;SEE IF IT'S A <TAB>
	BNE	I.DS01		;IF NOT THEN GO PUT IT OUT
	TST	B.STUS(R0)	;SEE IF WE'VE PUT IN ENOUGH SPACES
	BMI	I.DS08		;IF WE HAVE THEN OK
	JSR	PC,RTBYT	;ELSE RETURN IT TO THE BUFFER
	MOV	#' ,R1		;PRINT A SPACE
	MOV	R1,TTY0+2	;OUTPUT THE CHARACTER
	ADD	#010000,B.STUS(R0)	;ADD ONE TO THE POSITION COUNTER
	BR	I.DS03		;FINISH UP
I.DS01:	CMPB	R1,#015		;SEE IF A POSITION MODIFIER
	BEQ	I.DS05
	CMPB	R1,#012		;<CR>,<LF>,<FF> ARE THE ONES
	BEQ	I.DS05
	CMPB	R1,#014
	BEQ	I.DS07
	ADD	#010000,B.STUS(R0)	;MOVE OVER ROVER
	BIC	#100000,B.STUS(R0)	;CLEAR CONFLICT WITH <TAB>
I.DS02:	MOV	R1,TTY0+2	;OUTPUT THE CHARACTER
I.DS03:	TSTB	TTY0		;SEE IF ONE OF 20
	BMI	I.DS00		;IF READY FEED HIM AGAIN
I.DS04:	MOV	(SP)+,R1	;RESTORE THE REGISTERS
	MOV	(SP)+,R0
	RTI
I.DS0Z:	BIC	#100,@(R0)
	BR	I.DS04		;TURN OFF INTERRUPTS AND RETURN
I.DS07:	MOVB	#037,R1		;ERASE EOF
	JSR	PC,RTBYT		;FOR NEXT TIME
	MOVB	#035,R1		;HOME UP NOW
I.DS05:	BIC	#170000,B.STUS(R0)	;BACK TO POSITION ONE
	BR	I.DS02
I.DS08:	BIC	#170000,B.STUS(R0)	;CLEAR THE COUNTER
	BR	I.DS00

	BUFFER	20.,EB1,EB2	;40 CHARACTER ECHO BUFFER
	BUFFER	40.,TP1,TP2	;80 CHARACTER TTY BUFFER
	BUFFER	40.,KB1,KB2	;80 CHARACTER KBD BUFFER
	BUFFER	50.,HR1,HR2
	BUFFER	50.,HP1,HP2
	BUFFER	40.,LP1,LP2	;80 CHARACTER LPT BUFFER
INPUT:	MOV	R2,-(SP)	;SAVE THE REGS
	MOV	R1,-(SP)
	MOV	R0,-(SP)
	MOV	SLOTSI(R1),R0	;GET THE BUFFER ADDRESS
	BIC	#10,B.STUS(R0)	;CLEAR ^O
I.INP3:	SAVSTS			;GO TO LEVEL 7
	TSTB	B.SPEC(R0)	;SEE IF ANY LINES ARE HERE YET
	BEQ	I.INP0		;IF NONE THEN WAIT
	DECB	B.SPEC(R0)	;DECREMENT THE COUNT
I.INP1:	RSTSTS
I.INP5:	JSR	PC,GTBYT	;GET A BYTE
	MOVB	R1,(R2)+	;STORE IT
	CMPB	R1,#012		;SEE IF THAT'S IT
	BNE	I.INP5
	BIT	#400,B.STUS(R0)	;SEE IF WE STOPPED THE READER
	BEQ	I.INP2		;BRANCH IF NOT
I.INP8:	BIC	#400,B.STUS(R0)	;CLEAR THE STOPPED BIT AND RESTART IT
	MOVB	B.SPEC+1(R0),R1	;GET THE ALMOST FORGOTEN CHARACTER
	JSR	PC,PTBYT	;NOW THERE HAS TO BE ROOM
	BIS	#101,@(R0)	;RE-ENABLE THE READER
I.INP2:	MOV	(SP)+,R0	;RESTORE THE REGS
	MOV	(SP)+,R1
	MOV	(SP)+,R2
	RTS	PC		;AND RETURN
I.INP0:	RSTSTS
	BIT	#1000,B.STUS(R0)	;SEE IF EOF
	BNE	I.INP4
	BIT	#400,B.STUS(R0)	;SEE IF WE STOPPED THE READER
	BNE	I.INP6
	WAIT
	BR	I.INP3		;SOMETHING HAPPENED. WAS IT FOR US
I.INP4:	MOV	(SP)+,R0	;RESTORE THE REGS
	MOV	(SP)+,R1
	MOV	(SP)+,R2
	SEV				;SET EOF
	RTS	PC		;AND RETURN
I.INP6:	JSR	PC,GTBYT	;GET A BYTE
	BVS	I.INP7		;EXIT WHEN EMPTY
	MOVB	R1,(R2)+	;STORE THE THING
	BR	I.INP6
I.INP7:	CLRB	(R2)+
	MOVB	#012,(R2)+	;SHOW BAD LENGTH
	BR	I.INP8

OUTPUT:	MOV	R2,-(SP)	;SAVE THE REGS WE USE
	MOV	R1,-(SP)
	MOV	R0,-(SP)
	MOV	SLOTSO(R1),R0	;GET THE BUFFER ADDRESS
I.OUT2:	MOVB	(R2)+,R1	;GET A BYTE
	BEQ	I.OUT0
I.OUT3:	JSR	PC,PTBYT	;SEE IF THERE IS ROOM
	BVS	I.OUT1
	BIS	#100,@(R0)	;ENABLE INTERRUPTS NOW
	BR	I.OUT2		;LOOP FOR MORE
I.OUT1:	WAIT
	BR	I.OUT3		;WAS IT US-WAS IT US-HUH-HUH??
I.OUT0:	MOV	(SP)+,R0	;RESTORE THE REGS
	MOV	(SP)+,R1
	MOV	(SP)+,R2
	RTS	PC
	.END	START
                             